package designPatterns.com.course_design.scrapy.util;


import designPatterns.com.course_design.scrapy.logger.Log;
import designPatterns.com.course_design.scrapy.logger.LogFactory;

import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;

public class MyInvocationHandler {

    public final static Set<Integer> LogAnnotationFlags = new HashSet<>();

    public final static String log = "log";

    //参数obj：要 注入的对象  properName：属性名   value：属性值
    public static Object wire(Object obj, String properName, Object value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        //获取该类的类型
        Class<?> clazz = obj.getClass();
        Field field_name = null;
        try {
            //获取对象的属性
            field_name = clazz.getDeclaredField(properName);
        } catch (NoSuchFieldException ignored) {}
        try {
            if (field_name == null)
                field_name = clazz.getSuperclass().getDeclaredField(properName);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        if (field_name != null) {
            //开启访问权限
            field_name.setAccessible(true);
            //为该属性注入值
            field_name.set(obj, value);
        }
        //返回该对象
        return obj;
    }

    public static void wireLog(Object obj) throws NoSuchFieldException, IllegalAccessException {
        wire(obj, log, LogFactory.getInstance(obj.getClass()));
    }

    //参数obj：要 注入的对象  properName：属性名   value：属性值
    public static Object wireLogToFields(Object obj) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        //获取该类的类型
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            //获取对象的属性
            Field field_name = null;
            field_name = fields[i];
            //如果该属性被注解为Log...
            if (field_name.isAnnotationPresent(LogInjection.class)) {
                //开启访问权限
                field_name.setAccessible(true);
                //为该属性注入值
                field_name.set(obj, (Log) LogFactory.getInstance(clazz));
            } else {
                Object curObj = field_name.get(obj);
                wireLogToFields(curObj);
            }
        }
        //返回该对象
        return obj;
    }

}
